#include "parser.h"
#include "error.h"

double Parser::expr(bool get)//plus and minus
{
    double left = term(get);
    for(;;)
        switch(curr_tok)
        {
        case Lexer::PLUS:
            left += term(true);
            break;
        case Lexer::MINUS:
            left -= term(true);
            break;
        default:
            return left;
        }
}
double Parser::term(bool get)
{
    double left = prim(get);
    for(;;)
        switch(curr_tok){
        case Lexer::MUL:
            left *= prim(true);
            break;
        case Lexer::DIV:
            if(double d = prim(true)){
                left /= d;
                break;
            }
            return Error::error(std::string("divide by 0"));
        default:
            return left;
        }
}
double Parser::prim(bool get)
{
    if(get) Lexer::get_token();
    switch(Lexer::curr_tok){
    case Lexer::NUMBER:
    {
        double v = Lexer::number_value;
        Lexer::get_token();
        return v;
    }
    case Lexer::NAME:
    {
        double& v = Lexer::table[Lexer::string_value];
        if(Lexer::get_token() == Lexer::ASSIGN) v = expr(true);
        return v;
    }
    case Lexer::MINUS:
        return -prim(true);
    case Lexer::LP:
    {
        double e = expr(true);
        if(Lexer::curr_tok != Lexer::RP)return Error::error(") expected");
        Lexer::get_token();//eat ')'
        return e;
    }
    default:
        return Error::error("primary expected");
    }
}

